Next: Thread-Local, Previous: Pragmas, Up: C Extensions [Contents][Index]

### 6.58 Unnamed struct/union fields within structs/unions

As permitted by ISO C11 and for compatibility with other compilers, GCC allows you to define a structure or union that contains, as fields, structures and unions without names. For example:

    struct {
      int a;
      union {
        int b;
        float c;
      };
      int d;
    } foo;

In this example, the user would be able to access members of the unnamed union with code like ‘`foo.b`’. Note that only unnamed structs and unions are allowed, you may not have, for example, an unnamed `int`.

You must never create such structures that cause ambiguous field definitions. For example, this structure:

    struct {
      int a;
      struct {
        int a;
      };
    } foo;

It is ambiguous which `a` is being referred to with ‘`foo.a`’. The compiler gives errors for such constructs.

Unless `-fms-extensions` is used, the unnamed field must be a structure or union definition without a tag (for example, ‘`struct { int a; };`’). If `-fms-extensions` is used, the field may also be a definition with a tag such as ‘`struct foo { int a; };`’, a reference to a previously defined structure or union such as ‘`struct foo;`’, or a reference to a `typedef` name for a previously defined structure or union type.

The option `-fplan9-extensions` enables `-fms-extensions` as well as two other extensions. First, a pointer to a structure is automatically converted to a pointer to an anonymous field for assignments and function calls. For example:

    struct s1 { int a; };
    struct s2 { struct s1; };
    extern void f1 (struct s1 *);
    void f2 (struct s2 *p) { f1 (p); }

In the call to `f1` inside `f2`, the pointer `p` is converted into a pointer to the anonymous field.

Second, when the type of an anonymous field is a `typedef` for a `struct` or `union`, code may refer to the field using the name of the `typedef`.

    typedef struct { int a; } s1;
    struct s2 { s1; };
    s1 f1 (struct s2 *p) { return p->s1; }

These usages are only permitted when they are not ambiguous.

Next: Thread-Local, Previous: Pragmas, Up: C Extensions [Contents][Index]